#include "Core/EventManager.h"

namespace blue {

SINGLETON_IMPL(EventManager)

EventManager::EventManager()
{
}

EventManager::~EventManager()
{
}

void GLFWCALL eventKeyCallBack(int key, int action)
{
    EventManager::instance()->eventKeyCB(key, action);
}

void EventManager::eventKeyCB(int key, int action)
{
    _keyDown[key] = action;
}

void GLFWCALL eventMouseCallBack(int x, int y)
{
    EventManager::instance()->eventMouseCB(x, y);
}

void EventManager::eventMouseCB(int x, int y)
{
    _relX = _mouseX - _lastMouseX;
    _relY = _mouseY - _lastMouseY;
    _lastMouseX = _mouseX;
    _lastMouseY = _mouseY;
    _mouseX = x;
    _mouseY = y;
}

void GLFWCALL eventMouseButtonCallBack(int button, int action)
{
    EventManager::instance()->eventMouseButtonCB(button, action);
}

void EventManager::eventMouseButtonCB(int button, int action)
{
    _mouseButton[button] = action;
}

void EventManager::init(bool keyRepeat, bool stickyKeys, bool stickyMouseButtons)
{
    for(int i=0; i<NBKEYS; i++)
        _keyDown[i] = _keyOnce[i] = GLFW_RELEASE;

    for(int i=0; i<NBMOUSEBUTTONS; i++)
        _mouseButton[i] = GLFW_RELEASE;

    glfwDisable(GLFW_AUTO_POLL_EVENTS);

    if(keyRepeat) glfwEnable(GLFW_KEY_REPEAT);
    if(stickyKeys) glfwEnable(GLFW_STICKY_KEYS);
    if(stickyMouseButtons) glfwEnable(GLFW_STICKY_MOUSE_BUTTONS);

    glfwSetKeyCallback(eventKeyCallBack);
    glfwSetMousePosCallback(eventMouseCallBack);
    glfwSetMouseButtonCallback(eventMouseButtonCallBack);
}

void EventManager::getEvent()
{
    _relX = 0;
    _relY = 0;
    glfwPollEvents();
    _quit = !glfwGetWindowParam(GLFW_OPENED);
}

bool EventManager::isKeyDownOnce(int key)
{
    if(!_keyOnce[key])
    {
        if(_keyDown[key])
        {
            _keyOnce[key] = true;
            return true;
        }
    }
    else if(!_keyDown[key])
        _keyOnce[key] = false;

    return false;
}

bool EventManager::isKeyDown(int key) const
{
    return _keyDown[key];
}

bool EventManager::isMouseButtonUp(int button) const
{
    return _mouseButton[button];
}

int EventManager::getMouseX() const
{
    return _mouseX;
}

int EventManager::getMouseY() const
{
    return _mouseY;
}

int EventManager::getRelMouseX() const
{
    return _relX;
}

int EventManager::getRelMouseY() const
{
    return _relY;
}

bool EventManager::EventManager::quit() const
{
    return _quit;
}

}
